/*
 Copyright (c) Whitemice Consulting, 2007, 2008, 2009
 Adam Tauno Williams <awilliam@whitemice.org>
 License: MIT/X11

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/
using System;
using System.Collections;
using Gtk;
using Whitemice.ZOGI;
using Whitemice.ZOGI.GtkWidgets;
using Whitemice.ZOGI.GtkFolios;

namespace Whitemice.Consonance
{
  /// <summary>
  /// Task window, contains a task folio and related actions
  /// </summary>
	public partial class TaskWindow : EntityWindow
	{
		protected Whitemice.ZOGI.Task	                task;
		protected TaskFolio						                folio;
				
		public TaskWindow(Whitemice.ZOGI.Task task, int projectId, string projectName) : 
		  base(Gtk.WindowType.Toplevel)
		{
			this.Build();
			folio = new TaskFolio();
			folioArea.Child = folio;
			folio.DetailForm.OnExecutantChangeClicked += new EventHandler(OnExecutantSearch);
			folio.DetailForm.OnProjectChangeClicked += new EventHandler(OnProjectChange);
			folio.LinksTab.OnEntityPresent += new EntityEventHandler(Present);
			if (projectId > 0)
		    task.ProjectId = projectId;
  	  Fill(task);
		} // end ctor
		
		public TaskWindow(Whitemice.ZOGI.Task task) : this(task, 0, string.Empty)
		{
		} // end ctor

    public override Entity Current { get { return task; } }

    protected override void Fill(Entity entity)
    {
      this.ZLOG("Fill");
      this.EntityNameCheck(entity, typeof(Whitemice.ZOGI.Task));
      task = (entity as Whitemice.ZOGI.Task);
      //FreezeToDepth(1);
      Registry.RegisterForNotification(task, this);
      this.ZLOG("Calling folio.Fill");
      folio.Fill(Current);
      SetTitle();
      if (task.CanModify)
      {
      } else
        {
        }
    }

    protected void SetTitle()
    {
      this.Title = string.Format("Task#{0}:{1}", task.ObjectId, task.Name);
    }
    
		protected override bool Take()
		{
			return folio.Take(task);
		} // end Take

    protected override void SaveCallback(Entity entity, Exception exception, object context)
    {
      this.ZLOG(string.Format("SaveCallback(objectId#{0})", entity.ObjectId));
      folio.Fill(entity);
      Thaw();
    }

		[GLib.ConnectBefore]
		protected virtual void OnDeleteEvent(
			object sender, 
			Gtk.DeleteEventArgs args)
		{
			Close();
		} // end OnDeleteEvent 
			
		/// <summary>
		/// Receive a task into the window
		/// </summary>
		/// <param name="entity">
		/// A <see cref="Whitemice.ZOGI.Entity"/>
		/// </param>
		/// <param name="context">
		/// A <see cref="System.Object"/>
		/// </param>
		/// <param name="exception">
		/// A <see cref="System.Exception"/>
		/// </param>
		protected void ReceiveTask(Task entity)
		{
		  ArrayList availableActions;
		  
		  this.task = (entity as Task);
		  availableActions = ZOGIUtility.AvailableTaskActions(task);
		  // go to main thread
		  Application.Invoke(
		    delegate
		    {
		  	  Registry.RegisterForNotification(task, this);
		  	  if (task.ObjectId > 0)
		  		  Title = string.Format("Task#{0}:{1}", task.ObjectId, task.Name);
		   	  	else Title = "New Task";
		   	  folio.Fill(task);
		   	  //folio.HistoryForm.ResizeChildren();
          Thaw();
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Accept))
	  		    toolbarAccept.Sensitive = true;
	  	    	else toolbarAccept.Sensitive = false;
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Reject))
	  		    toolbarReject.Sensitive = true;
	  		    else toolbarReject.Sensitive = false;
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Comment))
	  		    toolbarComment.Sensitive = true;
	  		    else toolbarComment.Sensitive = false;
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Done))
	  		    toolbarDone.Sensitive = true;
	  		    else toolbarDone.Sensitive = false;
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Archive))
	  		    toolbarArchive.Sensitive = true;
	  		    else toolbarArchive.Sensitive = false;
	  	    if(availableActions.Contains(Whitemice.ZOGI.TaskAction.Activate))
	  		    toolbarActivate.Sensitive = true;
	  		    else toolbarActivate.Sensitive = false;
		     } // end main thread delegate
		   ); 
		} // end Fill 
		
		/// <summary>
		/// Receive a server event
		/// </summary>
		/// <param name="pEvent">
		/// A <see cref="Whitemice.ZOGI.ServerEvent"/>
		/// </param>
    public override void ProcessEvent(Whitemice.ZOGI.ServerEvent args)
    {
      switch(args.Event)
      {
        case ServerEventType.Update:
          Freeze();
          if (args.Entity is Whitemice.ZOGI.Task)
            ReceiveTask(args.Entity as Whitemice.ZOGI.Task);
            else throw new Exception("TaskWindow got an update of a non Task entity");
          Thaw();
          break;
      } // end event-switch
    } // end ReceiveEvent
		
		protected void ActionDialog(TaskAction action)
		{
			(new TaskActionDialog(this, task, action)).Run();
		} // end ActionDialog
				
		public void Print()
		{
			new MessageBox("Not Implemented");
		} // end Print 
		
		public void Close()
		{
			Unregister(task, true);
		} // end Close

		protected virtual void OnCancel(
		  object sender, 
		  System.EventArgs args)
		{
		  Close();
		} // end OnCancel 

		protected virtual void OnOK(
		  object sender, 
		  System.EventArgs args)
		{
			Save(task, true);
		} // end OnOk

		protected virtual void OnApply(
		  object sender, 
		  System.EventArgs args)
		{
	    Save(task, true);
		} // end OnApply 

		protected virtual void OnAccept(
			object sender, 
			System.EventArgs args)
		{
			ActionDialog(TaskAction.Accept);
		} // end OnAccept 

		protected virtual void OnReject(
			object sender, 
			System.EventArgs args)
		{
			ActionDialog(TaskAction.Reject);
		} // end OnReject
		
		protected virtual void OnComment(
			object sender, 
			System.EventArgs args)
		{
			ActionDialog(TaskAction.Comment);
		} // end OnComment 

		protected virtual void OnDone(
			object sender, 
			System.EventArgs args)
		{
			ActionDialog(TaskAction.Done);
		} // end OnDone 

		protected virtual void OnArchive(
			object sender, 
			System.EventArgs args)
		{
			ActionDialog(TaskAction.Archive);
		} // end OnArchive

		protected virtual void OnClose(
		  object sender, 
		  System.EventArgs args)
		{
		  Close();
		} // end OnClose

		protected virtual void OnPrint(
		  object sender, 
		  System.EventArgs args)
		{
		  Print();
		} // end OnPrint 

		protected virtual void OnSaveAs(
		  object sender, 
		  System.EventArgs args)
		{
		  new MessageBox("Not Implemented");
		} // end OnSaveAs 

		protected virtual void OnActivate(
		  object sender, 
		  System.EventArgs args)
		{
		  ActionDialog(TaskAction.Activate);
		} // end OnActivate
		
		protected virtual void OnExecutantSearch(
		  object sender,
		  System.EventArgs args)
	  {
	    ExecutantSearchDialog dialog;
	    
	    dialog = new ExecutantSearchDialog(
	      this, 
	      task.ObjectId, 
	      string.Format("Executant for Task#{0}", task.ObjectId));
	    dialog.SetExecutantId += 
	      new ExecutantSearchDialog.SetExecutantIdHandler(OnSetExecutant);
	    dialog.ShowAll();
	  } // end OnExecutantSearch
	  
	  protected virtual void OnSetExecutant(int executantId, string description)
	  {
	    folio.DetailForm.ExecutantId = executantId;
	    folio.DetailForm.ExecutantDescription = description;
	  } // end OnSetExecutant
	  
		protected virtual void OnProjectChange(
		  object sender,
		  System.EventArgs args)
	  {
	    ProjectSearchDialog dialog;
	    
	    dialog = new ProjectSearchDialog(
	      this,
	      task.ProjectId,
	      string.Format("Project for Project#{0}", task.ObjectId));
	    dialog.SetProjectId += 
	      new ProjectSearchDialog.SetProjectIdHandler(OnSetProject);
	    dialog.ShowAll();
	  }	// end OnProjectChange
	  
	  protected virtual void OnSetProject(int projectId, string description)
	  {
	    folio.DetailForm.ProjectId = projectId;
	    folio.DetailForm.ProjectDescription = description;
	  } // end OnSetProject

	  protected virtual void OnRefreshActionActivated (object sender, System.EventArgs e)
	  {
      folio.Fill(Current);
	  }
	} // end TaskWindow
} // end namespace